﻿using BaseDll;
using CommonTools;
using MotionIoLib;
using Newtonsoft.Json;
using OtherDevice;
using StationDemo.设备信息.data;
using StationDemo.设备信息.helper;
using System;
using System.ComponentModel;
using System.Threading;
using UserData;

namespace StationDemo.工站
{
    public class Param_Table
    {
        public ParamSet 顺时针转动 = new ParamSet()
        {
            _enuValType = ParamSetUnit.boolUnit,
            _strParamUnit = "顺时针转动",
            _strParamValMax = true,
            _strParamValMin = false,
            _strParamVal = true,
            _ParamRight = UserRight.Admin,
            _ParamClass = "转盘",
            b_IsStartCheck = true,
        };
    }

    public class Point_Table
    {
        public PointInfo 测试位置1上料位 = new PointInfo(0, 0, 0, 0, 0, 0, UserRight.Operator, "综合");
        public PointInfo 测试位置2上料位 = new PointInfo(0, 0, 0, 0, 0, 0, UserRight.Operator, "综合");
        public PointInfo 测试位置3上料位 = new PointInfo(0, 0, 0, 0, 0, 0, UserRight.Operator, "综合");
        public PointInfo 测试位置4上料位 = new PointInfo(0, 0, 0, 0, 0, 0, UserRight.Operator, "综合");
    }

    public class Config_Table
    {

    }

    public class Station_Table : CommonTools.StationbaseEx<Param_Table, Point_Table, Config_Table>
    {
        public enum StationStep
        {
            [Description("等待转动")]
            StepWait,

            [Description("转动")]
            StepTurn,

            [Description("结束")]
            StepEnd,
        }


        public Station_Table(CommonTools.Stationbase station, Param_Table param, Point_Table point, Config_Table config) : base(station, param, point, config)
        {

        }

        public StationData[] StationDatas { get; private set; } = new StationData[4]
        {
        new StationData(Station.三角测试1.ToString()),
        new StationData(Station.三角测试4.ToString()),
        new StationData(Station.三角测试3.ToString()),
        new StationData(Station.三角测试2.ToString()),
        };

        Collimator_Base 平行光管 => DeviceMgr.GetInstance().Function_获取串口("平行光管") as Collimator_Base;

        #region 主流程

        protected override void StationWork(int step)
        {
            try
            {
                switch (step)
                {
                    case (int)StationStep.StepWait:
                        DelCurrentStep();
                        PushMultStep((int)StepWait());
                        break;
                    case (int)StationStep.StepTurn:
                        DelCurrentStep();
                        PushMultStep((int)StepTurn());
                        break;
                    case (int)StationStep.StepEnd:
                        DelCurrentStep();
                        PushMultStep((int)StepEnd());
                        break;
                }
            }
            catch (Exception ex)
            {
                LogHelper.OnTest_ShowLog(Name, $"{Name} 发生错误:{ex.StackTrace},{ex.Message}", LogType.Err);
                StationMgr.GetInstance().Stop();
            }
        }

        protected override bool InitStation()
        {
            if (station_Param.顺时针转动._strParamVal)
            {
                StationDatas = new StationData[4]
            {
        new StationData(Station.三角测试1.ToString()),
        new StationData(Station.三角测试4.ToString()),
        new StationData(Station.三角测试3.ToString()),
        new StationData(Station.三角测试2.ToString()),
            };
            }
            else
            {
                StationDatas = new StationData[4]
            {
        new StationData(Station.三角测试4.ToString()),
        new StationData(Station.三角测试1.ToString()),
        new StationData(Station.三角测试2.ToString()),
        new StationData(Station.三角测试3.ToString()),
            };
            }
                

            ClearAllStep();
            PushMultStep((int)StationStep.StepWait);
            return true;
        }

        public override void PauseDeal()
        {

        }

        public override void ResumeDeal()
        {

        }

        public override void StopDeal()
        {

        }

        /// <summary>
        /// 等待转动信号
        /// </summary>
        /// <param name="bmanual"></param>
        /// <returns></returns>
        public StationStep StepWait(bool bmanual = false)
        {
            if (
                StationDatas[0].IsSingleStationEnd &&
            StationDatas[1].IsSingleStationEnd &&
            StationDatas[2].IsSingleStationEnd &&
            StationDatas[3].IsSingleStationEnd
                )
            {
                StationStateHelper.OnTest_ShowStep(Name, $"[{Name}]开始转动转盘", LogType.Warn);
                LogHelper.OnTest_ShowLog(Name, $"所有工位测试完成，下一步转动转盘", LogType.Warn);
                return StationStep.StepTurn;
            }
            StationStateHelper.OnTest_ShowStep(Name, $"[{Name}]等待转动..", LogType.Warn);
            return StationStep.StepWait;
        }

        /// <summary>
        /// 转动转盘并交换数据
        /// </summary>
        /// <param name="bmanual"></param>
        /// <returns></returns>
        public StationStep StepTurn(bool bmanual = false)
        {
            // 交换stationDatas数据

            PointInfo p = station_Point.测试位置1上料位;
            Station stat = (Station)Enum.Parse(typeof(Station), StationDatas[0].StationName);

            if (station_Param.顺时针转动._strParamVal)
            {
                switch (stat)
                {
                    case Station.三角测试1: p = station_Point.测试位置4上料位; break;
                    case Station.三角测试2: p = station_Point.测试位置1上料位; break;
                    case Station.三角测试3: p = station_Point.测试位置2上料位; break;
                    case Station.三角测试4: p = station_Point.测试位置3上料位; break;
                }
            }
            else
            {
                switch (stat)
                {
                    case Station.三角测试1: p = station_Point.测试位置2上料位; break;
                    case Station.三角测试2: p = station_Point.测试位置3上料位; break;
                    case Station.三角测试3: p = station_Point.测试位置4上料位; break;
                    case Station.三角测试4: p = station_Point.测试位置1上料位; break;
                }
            }


            LogHelper.OnTest_ShowLog(Name, $"开始转动转盘，目标上料工位:{p.GetType().Name}", LogType.Warn);
            LogHelper.OnTest_ShowLog(Name, $"开始转动转盘，目标位置:{JsonConvert.SerializeObject(p)}", LogType.Info);

            if (sys.g_AppMode == AppMode.AirRun)
            {
                Thread.Sleep(3000);
            }
            else
            {
                Function_运动到点位(p, bmanual);
            }

            StationStateHelper.OnTest_ShowStep(Name, $"[{Name}]转动结束", LogType.Warn);
            LogHelper.OnTest_ShowLog(Name, $"转动转盘完成", LogType.Info);
            return StationStep.StepEnd;
        }

        public StationStep StepEnd(bool bmanual = false)
        {
            LogHelper.OnTest_ShowLog(Name, $"交换前数据:{JsonConvert.SerializeObject(StationDatas)}", LogType.Info);
            ExchangeData();
            LogHelper.OnTest_ShowLog(Name, $"交换完数据:{JsonConvert.SerializeObject(StationDatas)}", LogType.Info);
            return StationStep.StepWait;
        }

        #endregion

        #region  方法
        public bool Function_工站回零()
        {

            UserDefineFunction.Axis_回零(AxisU, "转盘", this);

            return true;
        }

        public bool Function_气缸复位(bool bmanual = false)
        {
            return true;
        }

        private void ExchangeData()
        {

            if (station_Param.顺时针转动._strParamVal)
            {
                var item = StationDatas[0];
                for (int i = 0; i < StationDatas.Length - 1; i++)
                {
                    StationDatas[i] = StationDatas[i + 1];
                }
                StationDatas[StationDatas.Length - 1] = item;
            }
            else
            {
                var item = StationDatas[StationDatas.Length - 1];
                for (int i = StationDatas.Length - 1; i > 0; i--)
                {
                    StationDatas[i] = StationDatas[i - 1];
                }
                StationDatas[0] = item;
            }

            for (int i = 0; i < StationDatas.Length; i++)
                StationDatas[i].IsSingleStationEnd = false;
        }

        private void Function_运动到点位(PointInfo point, bool bmanual = false)
        {
            //转盘到指定点位必须先让平行光管和测试工位的U轴到达安全位
            StationHelper.Station_三角1.Function_图卡去安全位(bmanual);
            Thread.Sleep(1000);
            MoveMulitAxisPosWaitInpos(new int[] { AxisU }, new double[] { point.pointU }, new double[] { (double)SpeedType.High }, 0.5, bmanual, this);
        }


        #endregion


        #region 对外函数

        /// <summary>
        /// 通知转盘并且赋值工位数据
        /// </summary>
        /// <param name="station"></param>
        /// <param name="stationData"></param>
        public void NotifyTable(Station station, StationData stationData)
        {
            int index = 0;
            for (int i = 0; i < StationDatas.Length; i++)
            {
                if (StationDatas[i].StationName == station.ToString())
                {
                    index = i;
                    break;
                }
            }
            this.StationDatas[index] = ClassCloneHelper.Clone(stationData);
            this.StationDatas[index].IsSingleStationEnd = true;
        }

        /// <summary>
        /// 获取当前工位的数据
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public (StationData, int) StationDataByName(Station station)
        {
            for (int i = 0; i < StationDatas.Length; i++)
            {
                if (StationDatas[i].StationName == station.ToString())
                    return (StationDatas[i], i);
            }

            return (null, 0);
        }

        /// <summary>
        /// 获取指定工位的当前工作状态
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public bool GetWorkStatus(Station station)
        {
            for (int i = 0; i < StationDatas.Length; i++)
            {
                if (StationDatas[i].StationName == station.ToString())
                    return StationDatas[i].IsSingleStationEnd;
            }

            return true;
        }

        public bool Function_Set平行光管参数()
        {
            string Err = "";
            平行光管?.SetLight(1, Param_System.Instance.平行光管亮度值._strParamVal, ref Err, "白光"); if (Err.Contains("失败")) return false; Thread.Sleep(100);
            平行光管?.SetLight(5, Param_System.Instance.平行光管亮度值._strParamVal, ref Err, "白光"); if (Err.Contains("失败")) return false; Thread.Sleep(100);
            平行光管?.SetLight(6, Param_System.Instance.平行光管亮度值._strParamVal, ref Err, "白光"); if (Err.Contains("失败")) return false; Thread.Sleep(100);
            平行光管?.SetLight(7, Param_System.Instance.平行光管亮度值._strParamVal, ref Err, "白光"); if (Err.Contains("失败")) return false; Thread.Sleep(100);

            if (平行光管 == null)
            {
                LogHelper.OnTest_ShowLog(Name, "平行光管未连接", LogType.Err);
                return false;
            }
            if (平行光管.isConnect)
            {
                Thread.Sleep(200);
                string S = "";
                for (int i = 1; i < 20; i++)
                {
                    平行光管?.GetActPos((byte)i, ref S);
                }
                Thread.Sleep(200);
                float WDV = (float)Param_System.Instance.平行光管模拟距离值._strParamVal;
                if (WDV == 0)
                {
                    平行光管.MoveInf(ref S);
                }
                else
                {
                    平行光管?.MoveDistance(WDV, ref S);

                }

                if ((S.Contains("失败"))) return false;
            }

            return true;
        }

        public bool Function_复位平行光管()
        {
            bool bResult = true;
            string err = "";
            try
            {
                平行光管.Home(ref err, false);
            }
            catch (Exception ex)
            {
                LogHelper.OnTest_ShowLog(Name, ex.Message, LogType.Err);
                bResult = false;
            }

            if (err.Contains("失败")) bResult = false;

            LogHelper.OnTest_ShowLog(Name, $"平行光管鱼眼箱回零[{bResult}]");
            return bResult;
        }

        public void Function_转动转盘到上料位置(int stationNo)
        {
            PointInfo p = station_Point.测试位置1上料位;
            switch (stationNo)
            {
                case 1: p = station_Point.测试位置2上料位; break;
                case 2: p = station_Point.测试位置3上料位; break;
                case 3: p = station_Point.测试位置4上料位; break;
                case 4: p = station_Point.测试位置1上料位; break;
            }

            Function_运动到点位(p, true);
        }

        #endregion


    }
}
